using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace csammisrun.MsnLib
{
  public enum UserStatus
  {
    Offline,
    Available,
    Busy,
    Idle,
    Hidden,
    BeRightBack,
    Away,
    Phone,
    Lunch
  }

  public class User : IDisposable
  {
    internal static string GetStatusNameFromStatus(UserStatus status)
    {
      switch(status)
      {
        case UserStatus.Available:
          return "NLN";
        case UserStatus.Busy:
          return "BSY";
        case UserStatus.Idle:
          return "IDL";
        case UserStatus.BeRightBack:
          return "BRB";
        case UserStatus.Away:
          return "AWY";
        case UserStatus.Phone:
          return "PHN";
        case UserStatus.Lunch:
          return "LUN";
        case UserStatus.Offline:
          return "HDN";
        case UserStatus.Hidden:
          return "HDN";
      }
      return "NLN";
    }

    internal static UserStatus GetStatusFromName(string state)
    {
      switch (state)
      {
        case "NLN":
          return UserStatus.Available;
        case "BSY":
          return UserStatus.Busy;
        case "IDL":
          return UserStatus.Idle;
        case "BRB":
          return UserStatus.BeRightBack;
        case "AWY":
          return UserStatus.Away;
        case "PHN":
          return UserStatus.Phone;
        case "LUN":
          return UserStatus.Lunch;
        case "HDN":
          return UserStatus.Offline;
      }
      return UserStatus.Available;
    }

    private UserList _list = null;
    private UserStatus _status = UserStatus.Offline;
    private List<Group> _groups = new List<Group>();

    private MsnObject _object = null;

    private string _passport = "";
    private string _servername = "";
    private string _displayname = "";

    private bool _isidle = false;
    private bool _ismobile = false;

    public User(UserList list, string passport, string servername)
    {
      _list = list;
      _passport = passport;
      _servername = servername;
      _displayname = servername;
    }

    #region Methods
    public override string ToString()
    {
      return _passport;
    }

    public bool SetBuddyIcon(string filename)
    {
      FileStream icon = null;
      byte[] buffer = null;
      byte[] digest = null;
      int bytesread = 0;
      SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();

      // Set up the user's MSN object
      if (_object == null)
      {
        _object = new MsnObject(this, MsnObjectType.UserImage);
        _object.Location = "TFR2C2.tmp";
      }
      _object.RealLocation = filename;

      try
      {
        // Read the icon off-disk
        icon = new FileStream(filename, FileMode.Open, FileAccess.Read);
        buffer = new byte[icon.Length];
        while (bytesread < buffer.Length)
        {
          bytesread += icon.Read(buffer, bytesread, buffer.Length - bytesread);
        }
        icon.Close();
        _object.Size = buffer.Length;

        // Compute the data hash
        digest = sha1.ComputeHash(buffer);
        _object.SHA1D = Convert.ToBase64String(digest);

        // Compute the content hash
        _object.ComputeContentHash();
      }
      catch
      {
        // error scanner something happen
        _object = null;
        return false;
      }

      return true;
    }
    #endregion

    #region Properties
    /// <summary>
    /// Gets a list of groups to which this user belongs
    /// </summary>
    public List<Group> Groups
    {
      get { return _groups; }
    }

    public string Passport
    {
      get { return _passport; }
      set { _passport = value; }
    }

    /// <summary>
    /// Gets or sets the "friendly" name of the user
    /// </summary>
    public string DisplayName
    {
      get { return _displayname; }
      set { _displayname = value; }
    }

    /// <summary>
    /// Gets the name of the user that is stored on the server
    /// </summary>
    public string ServerName
    {
      get { return _servername; }
      set
      {
        if (_servername == "")
        {
          _servername = value;
        }
        else
          throw new Exception("ServerName cannot be changed after it has been set");
      }
    }

    public UserStatus Status
    {
      get { return _status; }
      set { _status = value; }
    }

    /// <summary>
    /// Gets or sets the user's MSN object
    /// </summary>
    public MsnObject Object
    {
      get { return _object; }
      set { _object = value; }
    }

    public UserList List
    {
      get { return _list; }
      set { _list = value; }
    }

    /// <summary>
    /// Gets or sets a value indicating whether this user is idle
    /// </summary>
    public bool IsIdle
    {
      get { return _isidle; }
      set { _isidle = value; }
    }

    /// <summary>
    /// Gets or sets a value indicating whether this user is using an MSN Mobile device
    /// </summary>
    public bool IsMobile
    {
      get { return _ismobile; }
      set { _ismobile = value; }
    }
    #endregion

    #region IDisposable Members

    public void Dispose()
    {
      if (_list != null)
      {
        _list.Dispose();
      }
    }

    #endregion
  }
}
